package practice;

// 线程 + 循环打印

// 三个线程，分别只能打印A，B和C
//要求按顺序打印ABC，打印10次

// 自己的错误写法：
/*public class CirclePrinter {
    public static void main(String[] args) {
        // 创建一个对象
        Object o1 = new Object();


        Thread A = new Thread(() -> {
            // 注意：先加锁 后循环！！
                synchronized (o1) { // 加锁
                    for (int i = 0; i < 10; i++) {
                        System.out.println("A");
                    try {
                        // 此时o1解锁，进入等待状态 下一个线程执行
                        o1.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        });

        Thread B = new Thread(() -> {
            synchronized (o1) { // 加锁
                for (int i = 0; i < 10; i++) {
                    System.out.println("B");
                    try {
                        // 此时o1解锁，进入等待状态 下一个线程执行
                        o1.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    o1.notify();
                }
            }

        });

        Thread C = new Thread(() -> {
            synchronized (o1) { // 加锁
                for (int i = 0; i < 10; i++) {
                    System.out.println("C");
                    try {
                        // 此时o1解锁，进入等待状态 下一个线程执行
                        o1.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    o1.notify();
                }
            }

        });

        A.start();
        B.start();
        C.start();
    }
}*/



// 参考网上代码
public class CirclePrinter extends Thread {
    private static Object o = new Object();
    private static int count = 0;  // 实际有效的序号  三个一轮
    private char ID;
    private int id;
    private int num = 0;  // 循环次数

    public CirclePrinter (int id, char ID) { // 构造方法
        this.id = id;
        this.ID = ID;
    }

    @Override
    public void run() {
        // 加锁：保证原子性+可重入性
        synchronized (o) {
            while (num < 10) {
                if (count % 3 == id) {
                    System.out.print(ID);
                    ++count;
                    ++num;
                    // 加在这里 只要一满足条件就换行！
                    if(count %3==0) {
                        System.out.printf("\n");
                    }
                    // 唤醒所有的线程:所有线程去竞争该锁，但是只有满足条件的才进行打印
                    o.notifyAll();
                } else {
                    // 线程中不满足的线程进入等待状态
                    // 线程进入等待状态 解锁
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 如果换行操作卸载这儿 会直接空一行  因为这个执行完后才可以去加锁，重新输出
                }

            }
        }
    }

    public static void main(String[] args) {
        (new CirclePrinter(0, 'A')).start();
        (new CirclePrinter(1, 'B')).start();
        (new CirclePrinter(2, 'C')).start();
    }
}

